#ifndef _PROTOCOL_
#define _PROTOCOL_

#include <iostream>
#include "Log.hpp"
#include <string>
#include <cstring>
#include <jsoncpp/json/json.h>

#define SPACE " "
#define SPACE_SIZE strlen(" ")
#define DEC_LENGTH strlen("\r\n") // 不能使用sizeof，因为字符串会将\0算入
#define DECOLL "\r\n"

namespace Ser_Change
{
    // 负责数据正反序列化
    class DataConversion
    {
    public:
        DataConversion() : _a(0), _b(0), _synbol("") {}
        DataConversion(int a, int b, std::string sy)
            : _a(a), _b(b), _synbol(sy) {}

        // 使用更加规范的协议:
        // “lenght\r\n123+4321\r\n”
        // 在客户端高并发的情况下，对服务端socket缓冲区满载打入，服务端可以一次接收数据

#ifndef __MYJSON__
        std::string serialize()
        {
            Json::Value send;
            send["_a"] = _a;
            send["_b"] = _b;
            send["_synbol"] = _synbol;
            Json::FastWriter fastwriter;
            return move(fastwriter.write(send));
        }

#else
        // 转序列化 “1 + 1” 转换
        std::string serialize()
        {
            std::string tmp;
            tmp += std::to_string(_a);
            tmp += SPACE;
            tmp += _synbol;
            tmp += SPACE;
            tmp += std::to_string(_b);

            std::string data;
            data += std::to_string(tmp.size());
            data += DECOLL;
            data += tmp;
            data += DECOLL;

            return move(data);
        }
#endif

#ifndef __MYJSON__
        std::string Disserialize(std::string &str)
        {

            Json::Value accept;
            Json::Reader reader;
            reader.parse(str, accept);
            _a = accept["_a"].asInt();
            _b = accept["_b"].asInt();
            _synbol = accept["_synbol"].asString();

            std::string surplus = str.substr(accept.size());
            str.erase(0, accept.size());
            if (str.empty())
                std::cout << "empty" << std::endl;

            return move(surplus);
        }
#else
        // 反序列化  "1 + 2"
        std::string Disserialize(std::string &str)
        {
            size_t left = str.find(DECOLL);
            size_t tail = str.find(DECOLL, left + DEC_LENGTH);
            // “lenght\r\n123 + 4321\r\n”
            if (left != str.npos && atoi(str.substr(0, left).c_str()) == tail - left - DEC_LENGTH)
            // 检测数据包,是否包含1个完整包
            {
                size_t left_data = str.find(SPACE);
                size_t tail_data = str.rfind(SPACE, tail);
                _a = atoi(str.substr(left + DEC_LENGTH, left_data - left - DEC_LENGTH).c_str());
                _synbol = str.substr(left_data + SPACE_SIZE, SPACE_SIZE);
                _b = atoi(str.substr(tail_data + SPACE_SIZE, tail - tail_data - SPACE_SIZE).c_str());

                std::string surplus = str.substr(DEC_LENGTH);
                str.erase(0, tail + DEC_LENGTH);
                return move(surplus); // 返回拷贝后的剩余字段
            }
            else
            {
                return "";
            }
        }
#endif

        // private:
        int _a;
        int _b;
        std::string _synbol;
    };

    // 负责结果和状态码的正反序列化
    class Response
    {
    public:
        Response() : _result(0), _code(0) {}
        // 状态码默认 0 未设置, -1 异常 ，1 以设置
        Response(int res, int code = 0)
            : _result(res), _code(code)
        {
        }
#ifndef __MYJSON__
        std::string serialize()
        {
            Json::Value send;
            send["result"] = _result;
            send["code"] = _code;
            Json::FastWriter writer;
            return move(writer.write(send));
        }

        bool Disserialize(std::string &str, int *result)
        {
            Json::Value accept;
            Json::Reader reader;
            reader.parse(str, accept);
            _result = accept["result"].asInt();
            _code = accept["code"].asInt();
            *result = _result;
            return 1;
        }
#else
        // 转序列化 “12  2” 转换
        std::string serialize()
        {
            std::string tmp;
            _code = 1;
            tmp += std::to_string(_result);
            tmp += " ";
            tmp += std::to_string(_code);

            std::string data;
            data += std::to_string(tmp.size());
            data += DECOLL;
            data += tmp;
            data += DECOLL;

            return move(data);
        }

        // 反序列化  "1  2"包中提取一个数据包，并且完成后进行删除
        bool Disserialize(std::string &str, int *result)
        {
            // size_t left = str.find(" ");
            // size_t tail = str.rfind(" ");
            // if (left != str.npos && tail == left)
            // {
            //     _result = atoi(str.substr(0, left).c_str());
            //     _code = atoi(str.substr(left + 1, 1).c_str());
            //     *result = _result;
            //     return 1;
            // }
            // else
            // {
            //     return false;
            // }

            size_t left = str.find(DECOLL);
            size_t tail = str.find(DECOLL, left + DEC_LENGTH);
            // “lenght\r\n123 + 4321\r\n”
            if (left != str.npos && atoi(str.substr(0, left).c_str()) == tail - left - DEC_LENGTH) // 检测数据包
            {
                size_t left_data = str.find(SPACE);
                _result = atoi(str.substr(left + DEC_LENGTH, left_data - left - DEC_LENGTH).c_str());
                _code = atoi(str.substr(left_data + SPACE_SIZE, tail - left_data - SPACE_SIZE).c_str());
                str.erase(0, tail + DEC_LENGTH);
                *result = _result;
            }
            else
            {
                return false;
            }
        }
#endif
        // private:
        int _result; // 结果
        int _code;   // 状态码
    };
}

#endif
